package com.lml.gpt;

import org.junit.jupiter.api.Test;

/**
 * @author luomingliang
 * @date 2023/3/12 21:52
 */
public class Test01 {

    /**
     * 校验身份证号码
     *
     * @param idCard
     * @return
     */
    public static boolean isValidIDCard(String idCard) {
        boolean result = false;
        // 判断身份证号不为空并且为18位
        if (idCard != null && idCard.length() == 18) {
            try {
                // 身份证号的格式正则表达式
                /**
                 * ^                    // 匹配字符串的开头
                 * \\d{6}               // 前6位为行政区划代码
                 * (19|20)\\d{2}        // 7-10位为年份"19xx"或"20xx"
                 * (0[1-9]|1[0-2])      // 11-12位为月份 01-12
                 * (0[1-9]|[12]\\d|3[01])  // 13-14位为日 01-31
                 * \\d{3}               // 15-17位为顺序号
                 * [\\dXx]              // 18位为校验码 X或x表示10
                 * $                    // 匹配字符串的结尾
                 */
                String regex = "^\\d{6}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$";
                // 如果身份证号格式符合要求则进行下一步校验
                if (idCard.matches(regex)) {
                    // 身份证号每位的权值因子
                    int[] factors = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
                    // 身份证号最后一位的校验码
                    char[] checkCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
                    int sum = 0;
                    // 计算身份证号每位与对应位的权值因子的乘积之和
                    for (int i = 0; i < factors.length; i++) {
                        sum += factors[i] * Integer.parseInt(idCard.substring(i, i + 1));
                    }
                    // 校验身份证号的最后一位校验码是否正确
                    char checkCode = checkCodes[sum % 11]; // 通过权值因子的乘积相加取模11得到对应的校验码
                    result = idCard.charAt(17) == checkCode; // 判断身份证号的最后一位是否与计算出的校验码一致
                }
            } catch (NumberFormatException e) {
                // ignore
            }
        }
        return result;
    }
    /**
     * 权值因子和循环的作用是计算和校验身份证号。
     * 在中国的身份证号中，前17位是固定位，而最后一位是校验码。校验码是利用前17位的数字按照一定规则计算得到的。计算规则如下：
     * 根据身份证号前17位每位与对应位的权值因子的乘积之和sum，计算sum % 11的值，根据这个值查询一个“校验码表”，从而得到校验码。这个“校验码表”中的数据是手动曾经积累下来的，是一个固定值数组。
     * 循环的作用是遍历前17位的每一位，并将其与对应的权值因子相乘得到mul值，最后将这些mul值相加求和得到sum值。最后，校验身份证号的最后一位校验码是否正确，是通过比较身份证号的最后一位和计算出的校验码是否一致来实现的。
     * 总之，权值因子和循环的作用就是将身份证号的前17位数字按照一定规则计算出一个能够唯一对应的校验码。这个校验码就是用来验证身份证号是否正确的。
     */

    /**
     * 校验手机号
     *
     * @param mobileNumber
     * @return
     */
    public static boolean isValidMobileNumber(String mobileNumber) {
        boolean result = false;
        if (mobileNumber != null && mobileNumber.matches("^1[3-9]\\d{9}$")) {
            result = true;
        }
        return result;
    }

    /**
     * 校验邮箱
     *
     * @param email
     * @return
     */
    public static boolean isValidEmail(String email) {
        boolean result = false;
        if (email != null && email.matches("^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")) {
            result = true;
        }
        return result;
    }

    @Test
    public void test1() {
        System.out.println(isValidEmail("asdas@qq.com"));
        System.out.println(isValidMobileNumber("18812341234"));
        System.out.println(isValidIDCard("130521199504040014"));
    }
}
